package com.motong.gongdan.service;

import com.alibaba.excel.util.IoUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.motong.gongdan.config.auth.LoginException;
import com.motong.gongdan.entity.*;
import com.motong.gongdan.mapper.*;
import com.motong.gongdan.util.*;
import com.motong.gongdan.vo.system.CustomField.ColumnsConfigure;
import com.motong.gongdan.vo.system.CustomField.ColumnsConfigureList;
import com.motong.gongdan.vo.system.otherVo.CustomFieldVo;
import com.motong.gongdan.vo.system.otherVo.ExcelImportLog;
import com.motong.gongdan.vo.system.otherVo.MenuJsonVo;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;

@Service
public class UserService extends ServiceImpl<UserMapper, User> {
    @Resource
    FactoryService factoryService;
    @Resource
    DatabaseListService databaseListService;
    @Resource
    CustomFieldService customFieldService;
    @Resource
    UserService userService;
    @Resource
    DepartmentsService departmentsService;
    @Resource
    private BadProductMapper badProductMapper;
    @Resource
    private CustomEventMapper customEventMapper;
    @Resource
    private DepartmentsMapper departmentsMapper;
    @Resource
    private DimensionCombinationMapper dimensionCombinationMapper;
    @Resource
    private EventLogMapper eventLogMapper;
    @Resource
    private FormTableMapper formTableMapper;
    @Resource
    private FormTableDetailMapper formTableDetailMapper;
    @Resource
    private HandleLogMapper handleLogMapper;
    @Resource
    private MatchingRuleMapper matchingRuleMapper;
    @Resource
    private MissionMapper missionMapper;
    @Resource
    private ProcessRouteMapper processRouteMapper;
    @Resource
    private ProcessesMapper processesMapper;
    @Resource
    private ProductMapper productMapper;
    @Resource
    private ReportBadProductMapper reportBadProductMapper;
    @Resource
    private StockDetailMapper stockDetailMapper;
    @Resource
    private StockMsgMapper stockMsgMapper;
    @Resource
    private UnitMapper unitMapper;
    @Resource
    private WagesMapper wagesMapper;
    @Resource
    private WorkOrderMapper workOrderMapper;
    @Resource
    private WorkReportMapper workReportMapper;
    @Resource
    private MobileCardConfMapper mobileCardConfMapper;
    @Resource
    private ScreenPlanMapper screenPlanMapper;


    public DatabaseList getRedisDatabase(Integer factoryId) {
        Factory factory = factoryService.getById(factoryId);
        DatabaseList dl = databaseListService.getOne(new QueryWrapper<DatabaseList>().eq("factory_code", factory.getCode()));
        return dl;
    }

    public void importLog(String account, Integer count, Map<String, Integer> dataMap, String type, List<Map<String, String>> reason) {
        ExcelImportLog eil = new ExcelImportLog();
        eil.setAccount(account);
        eil.setCount(count);
        eil.setCreateTime(new Date());
        eil.setData(dataMap);
        eil.setReason(reason);
        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(eil));
        JSONArray jsonArray = (JSONArray) RedisUtil.get("excel:import:" + type + ":" + LoginUtil.getLoginUserFactory());
        if (jsonArray == null) {
            jsonArray = new JSONArray();
        }
        jsonArray.add(jsonObject);
        RedisUtil.set("excel:import:" + type + ":" + LoginUtil.getLoginUserFactory(), jsonArray, 259200);
    }

    public List<ColumnsConfigureList> handleDefault() {
        String str = OwnUtil.readFileTxt("importModelColumns.txt");
        JSONArray jsonArray = JSON.parseArray(str);
        List<ColumnsConfigureList> allList = jsonArray.toJavaList(ColumnsConfigureList.class);
        return allList;
    }

    public void handleImport(MultipartFile file) throws IOException {
        byte[] stream = IoUtils.toByteArray(file.getInputStream());
        List<Map<String, String>> allDataList = EasyExcelImportUtils.parseExcelToData(stream, 2, "账号");
        // 空值导入日志
        userService.importBlankExcel(allDataList, "user");

        List<ColumnsConfigureList> allList = handleDefault();
        Map<String, Integer> dataMap = new HashMap<>();
        List<Map<String, String>> failList = new ArrayList<>();
        int a = 0;
        int b = 0;
        List<ColumnsConfigure> defaultColumns = customFieldService.handleImportDefault("user");
        if (allList.stream().filter(f -> f.getType().equals("user")).findAny().orElse(null) != null) {
            List<ColumnsConfigure> list = allList.stream().filter(f -> f.getType().equals("user")).findAny().orElse(null).getColumns();
            String depS = "";
            for (Map<String, String> s : allDataList) {
                Map<String, String> failMap = new HashMap<>();
                User u = new User();
                List<CustomFieldVo> vos = new ArrayList<>();
                //表头
                List<String> keyList = new ArrayList<>(s.keySet());
                if (!defaultColumns.stream().filter(f -> f.getChineseName().equals(keyList.get(0))).findAny().isPresent()) {
                    failMap.put("失败原因", "模版读取错误");
                    failList.add(failMap);
                    b++;
                    break;
                }
                int flag = 0;
                for (int i = 0; i < keyList.size() && flag == 0; i++) {
                    if (i >= list.size()) {
                        if (StringUtil.isNotBlank(keyList.get(i)) && StringUtil.isNotBlank(s.get(keyList.get(i)))) {
                            CustomField cf = customFieldService.getOne(new QueryWrapper<CustomField>().eq("field_ascription", "user").eq("chinese_name", keyList.get(i)));
                            CustomFieldVo vo = new CustomFieldVo();
                            vo.setCustomFieldId(cf.getId());
                            vo.setValue(s.get(keyList.get(i)));
                            vos.add(vo);
                        }
                    } else {
                        switch (i) {
                            case 0:
                                if (StringUtil.isNotBlank(s.get(keyList.get(i)))) {
                                    User old = userService.getOne(new QueryWrapper<User>().eq("account", s.get(keyList.get(i))));
                                    if (old == null) {
                                        u.setAccount(s.get(keyList.get(i)));
                                    } else {
                                        failMap.put("失败原因", "用户账号已存在");
                                        failMap.put("账号", s.get(keyList.get(i)));
                                        failMap.put("姓名", s.get(keyList.get(i + 1)));
                                        failMap.put("手机号", s.get(keyList.get(i + 2)));
                                        failList.add(failMap);
                                        b++;
                                        flag = 1;
                                        break;
                                    }
                                }
                                continue;
                            case 1:
                                if (StringUtil.isBlank(s.get(keyList.get(i)))) {
                                    failMap.put("失败原因", "姓名不能为空");
                                    failList.add(failMap);
                                    b++;
                                    flag = 1;
                                    break;
                                } else {
                                    u.setName(s.get(keyList.get(i)));
                                }
                                continue;
                            case 2:
                                if (StringUtil.isBlank(s.get(keyList.get(i)))) {
                                    failMap.put("失败原因", "密码不能为空");
                                    failList.add(failMap);
                                    b++;
                                    flag = 1;
                                    break;
                                } else {
                                    u.setPassword(MD5Util.generate(s.get(keyList.get(i))));
                                }
                                continue;
                            case 3:
                                if (StringUtil.isNotBlank(s.get(keyList.get(i)))) {
                                    u.setMobile(s.get(keyList.get(i)));
                                }
                                continue;
                            case 4:
                                if (StringUtil.isNotBlank(s.get(keyList.get(i)))) {
                                    u.setRole(s.get(keyList.get(i)));
                                }
                                continue;
                            case 5:
                                if (StringUtil.isNotBlank(s.get(keyList.get(i)))) {
                                    depS = s.get(keyList.get(i));
                                }
                                continue;
                            case 6:
                                if (StringUtil.isNotBlank(s.get(keyList.get(i)))) {
                                    u.setVirtualType(s.get(keyList.get(i)).equals("1") ? 1 : 0);
                                }
                                continue;
                        }
                    }
                }
                if (flag == 0) {
                    if (!CollectionUtils.isEmpty(vos)) {
                        u.setOther(customFieldService.handleObjectCreateOrEdit(vos).toJSONString());
                    }
                    u.setCreateTime(new Date());
                    u.setUpdateTime(new Date());
                    u.setFactoryId(LoginUtil.getLoginUserFactory());
                    boolean result = userService.save(u);
                    if (result) {
                        a++;
                    }
                    if (StringUtil.isNotBlank(depS)) {
                        String finalDepS = depS;
                        Arrays.asList(depS.split(",")).forEach(d -> {
                            Departments dep = departmentsService.getOne(new QueryWrapper<Departments>().eq("code", d));
                            if (dep != null) {
                                dep.setIds(dep.getIds() + "," + u.getId());
                            } else {
                                dep = new Departments();
                                dep.setCode(StringUtil.getCode("dep"));
                                dep.setName(finalDepS);
                                dep.setCreateTime(new Date());
                                dep.setUpdateTime(new Date());
                                dep.setCreateName(LoginUtil.getLoginAccount());
                                dep.setCreatePerson(LoginUtil.getLoginUserId());
                                dep.setIds(u.getId().toString());
                            }
                            departmentsService.saveOrUpdate(dep);
                            u.setDepId(dep.getId().toString());
                            userService.updateById(u);
                        });
                    }
                }
            }
            dataMap.put("createSuccess", a);
            dataMap.put("createFail", b);
            userService.importLog(LoginUtil.getLoginAccount(), allDataList.size(), dataMap, "user", failList);
        }

    }


    /**
     * 空excel导入记录
     *
     * @param data       需要判断的数据
     * @param moduleName 模块名称
     */
    public void importBlankExcel(Object data, String moduleName) {
        if (Objects.isNull(data)) {
            Map<String, Integer> blankMap = new HashMap<>(2);
            blankMap.put("createSuccess", 0);
            blankMap.put("createFail", 0);
            blankMap.put("updateSuccess", 0);
            blankMap.put("updateFail", 0);
            this.importLog(LoginUtil.getLoginAccount(), 0, blankMap, moduleName, null);
            throw new LoginException("200", "导入完成");
        }
    }

    public void delAllData(Integer loginUserFactory) {
        badProductMapper.delete(new LambdaQueryWrapper<BadProduct>()/*.eq(BadProduct::getFactoryId, loginUserFactory)*/);
        customEventMapper.delete(new LambdaQueryWrapper<CustomEvent>()/*.eq(CustomEvent::getFactoryId, loginUserFactory)*/);
        customFieldService.remove(new LambdaQueryWrapper<CustomField>()/*.eq(CustomField::getFactoryId, loginUserFactory)*/);
        departmentsMapper.delete(new LambdaQueryWrapper<Departments>()/*.eq(Departments::getFactoryId, loginUserFactory)*/);
        dimensionCombinationMapper.delete(new LambdaQueryWrapper<DimensionCombination>()/*.eq(DimensionCombination::getFactoryId, loginUserFactory)*/);
        eventLogMapper.delete(new LambdaQueryWrapper<EventLog>()/*.eq(EventLog::getFactoryId, loginUserFactory)*/);
        formTableMapper.delete(new LambdaQueryWrapper<FormTable>()/*.eq(FormTable::getFactoryId, loginUserFactory)*/);
        formTableDetailMapper.delete(new LambdaQueryWrapper<FormTableDetail>()/*.eq(FormTableDetail::getFactoryId, loginUserFactory)*/);
        handleLogMapper.delete(new LambdaQueryWrapper<HandleLog>()/*.eq(HandleLog::getFactoryId, loginUserFactory)*/);
        matchingRuleMapper.delete(new LambdaQueryWrapper<MatchingRule>()/*.eq(MatchingRule::getFactoryId, loginUserFactory)*/);
        missionMapper.delete(new LambdaQueryWrapper<Mission>()/*.eq(Mission::getFactoryId, loginUserFactory)*/);
        processRouteMapper.delete(new LambdaQueryWrapper<ProcessRoute>()/*.eq(ProcessRoute::getFactoryId, loginUserFactory)*/);
        processesMapper.delete(new LambdaQueryWrapper<Processes>()/*.eq(Processes::getFactoryId, loginUserFactory)*/);
        productMapper.delete(new LambdaQueryWrapper<Product>()/*.eq(Product::getFactoryId, loginUserFactory)*/);
        reportBadProductMapper.delete(new LambdaQueryWrapper<ReportBadProduct>()/*.eq(ReportBadProduct::getFactoryId, loginUserFactory)*/);
        stockDetailMapper.delete(new LambdaQueryWrapper<StockDetail>()/*.eq(StockDetail::getFactoryId, loginUserFactory)*/);
        stockMsgMapper.delete(new LambdaQueryWrapper<StockMsg>()/*.eq(StockMsg::getFactoryId, loginUserFactory)*/);
        unitMapper.delete(new LambdaQueryWrapper<Unit>()/*.eq(Unit::getFactoryId, loginUserFactory)*/);
        wagesMapper.delete(new LambdaQueryWrapper<Wages>()/*.eq(Wages::getFactoryId, loginUserFactory)*/);
        workOrderMapper.delete(new LambdaQueryWrapper<WorkOrder>()/*.eq(WorkOrder::getFactoryId, loginUserFactory)*/);
        workReportMapper.delete(new LambdaQueryWrapper<WorkReport>()/*.eq(WorkReport::getFactoryId, loginUserFactory)*/);
        mobileCardConfMapper.delete(new LambdaQueryWrapper<MobileCardConf>()/*.eq(MobileCardConf::getFactoryId, loginUserFactory)*/);
        screenPlanMapper.delete(new LambdaQueryWrapper<ScreenPlan>()/*.eq(ScreenPlan::getFactoryId, loginUserFactory)*/);
    }

    public List<MenuJsonVo> getCurrentUserPermission() {
        Integer userId = LoginUtil.getLoginUserId();
        JSONArray jsonArray = (JSONArray) RedisUtil.get("permissions:workOrder:" + userId);
        if (jsonArray != null && !jsonArray.isEmpty()) {
            return jsonArray.toJavaList(MenuJsonVo.class);
        }
        return Collections.emptyList();
    }
}
